<template>
  <div
    class="_wrapper _p20 _box-scroll"
    style="background-color: black"
    v-loading="loadingTag"
  >
    <div ref="refTerm" class="_wrapper _over-scroll-hidden"></div>
  </div>
</template>

<script>
import toolWin from "@/tool/tool-window";
import { Terminal } from "xterm";
import "xterm/css/xterm.css";

let websocket;
let term;

function writeLine() {
  term.write("\r\n\x1b[33m$\x1b[0m ");
}

function sendData(command) {
  websocket.send(
    JSON.stringify({
      operate: "command",
      command,
    })
  );
}

export default {
  props: {
    sshOption: {
      type: Object,
      required: true,
    },
  },
  data() {
    return {
      loadingTag: true,
      command: "",
      sshPrompt: "",
    };
  },
  methods: {
    initTerm() {
      if (term) {
        return;
      }
      term = new Terminal({
        rendererType: "canvas", //渲染类型
        cols: 97,
        rows: 200,
        cursorBlink: true, // 光标闪烁
        cursorStyle: "block", // 光标样式  null | 'block' | 'underline' | 'bar'
        scrollback: 800, //回滚
        tabStopWidth: 8, //制表宽度
        screenKeys: true,
        theme: {
          foreground: "#ECECEC", //字体
          background: "#000000", //背景色
          cursor: "help", //设置光标
          lineHeight: 40,
        },
      });

      term.open(this.$refs["refTerm"], true);
      writeLine();
      term.focus();

      this.loadingTag = false;

      term.onData((key) => {
        if (key.charCodeAt(0) == 13) {
          // 回车
          if (this.command === "clear") {
            term.clear();
          }
          if (this.command.trim().length === 0) {
            // term.prompt();
          } else {
            // 保存命令
            let commands = localStorage.getItem("commands")
              ? JSON.parse(localStorage.getItem("commands"))
              : [];
            commands.push(this.command);
            localStorage.setItem("commands", JSON.stringify(commands));
            localStorage.setItem("index", commands.length);
            sendData(this.command);
          }
          this.command = "";
          writeLine();
        } else if (key === "\u001b[A") {
          // 向上方向
          let commands = localStorage.getItem("commands")
            ? JSON.parse(localStorage.getItem("commands"))
            : [];
          // console.log(commands)
          let index = localStorage.getItem("index")
            ? localStorage.getItem("index")
            : commands.length;
          index = parseInt(index);
          if (commands.length && index < commands.length + 1 && index > 0) {
            // 删除现有命令
            for (let i = 0; i < this.command.length; i++) {
              if (term._core.buffer.x > this.sshPrompt.length + 2) {
                term.write("\b \b");
              }
            }
            this.command = commands[index - 1];
            term.write(this.command);
            localStorage.setItem("index", index - 1);
          }
        } else if (key === "\u001b[B") {
          // 向下方向
          let commands = localStorage.getItem("commands")
            ? JSON.parse(localStorage.getItem("commands"))
            : [];
          let index = localStorage.getItem("index")
            ? localStorage.getItem("index")
            : commands.length;
          index = parseInt(index);
          if (commands.length && index < commands.length - 1 && index > -1) {
            // 删除现有命令
            for (let i = 0; i < this.command.length; i++) {
              if (term._core.buffer.x > this.sshPrompt.length + 2) {
                term.write("\b \b");
              }
            }
            this.command = commands[index + 1];
            term.write(this.command);
            localStorage.setItem("index", index + 1);
          }
        } else if (key.charCodeAt(0) === 9) {
          // tab键
          let params = {
            consoleUUID: this.activeMsf,
            cmd: this.command,
          };
          // tab补全
          this.$apis.readTabsComplete(params).then((res) => {
            if (res.code === 200) {
              if (res.data.length) {
                for (let i = 0; i < this.command.length; i++) {
                  term.write("\b \b");
                }
                let data = res.data.join("\r\n");
                this.command = res.data[res.data.length - 1];
                if (res.data.length > 1) {
                  term.write("\r\n");
                  term.write(data);
                  term.prompt();
                  term.write(res.data[res.data.length - 1]);
                } else {
                  term.write(this.command);
                }
              }
            } else {
              this.$message.error(res.message());
            }
          });
        } else if (key.charCodeAt(0) === 127) {
          if (term._core.buffer.x > this.sshPrompt.length + 2) {
            term.write("\b \b");
            this.command = this.command.substr(0, this.command.length - 1);
          }
        } else {
          this.command += key;
          term.write(key);
        }
      });
    },
    initWebSocket() {
      websocket = new WebSocket(
        `ws://127.0.0.1:33610/ws?token=${this.$comStore.login.token}`
      );

      toolWin.onDestoryExist(this.$refs["refTerm"]).then(() => {
        // websocket.close();
      });

      websocket.onmessage = (msg) => {
        if (msg.data === "ok") {
          this.initTerm();
        } else if (term && msg.data && msg.data.length > 0) {
          //收到数据时回调
          term.write(msg.data.replace(/[\n\r]{2,}/g, "\r\n"));
        }
      };

      websocket.onerror = (error) => {
        //连接失败回调
        console.log(`output->error`, error);
        term && term.write("Error: " + error + "\r\n");
      };

      websocket.onclose = () => {
        //连接关闭回调
        console.log("websocket 关闭...");
        term && term.write("\r\nconnection closed");
      };

      websocket.onopen = () => {
        //连接成功回调
        websocket.send(
          JSON.stringify({
            operate: "connect",
            ...this.sshOption,
            // host: "116.255.130.173", //IP
            // port: "22", //端口号
            // username: "root", //用户名
            // password: "gainet!@#456", //密码
          })
        );
        console.info("webssh 初始化参数！", this.sshOption);
      };
    },
  },
  mounted() {
    term = undefined;
    this.initWebSocket();
  },
  unmounted() {
    websocket.close();
  },
};
</script>

<style>
.xterm-viewport {
  overflow: hidden !important;
}
</style>
